package com.clinic.logic.user;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.clinic.accessor.db.DoctorAccessor;
import com.clinic.accessor.db.UserContactAccessor;
import com.clinic.entity.db.Doctor;
import com.clinic.entity.db.UserContact;
import com.clinic.entity.gui.GuiDoctor;
import com.clinic.entity.gui.GuiPagination;
import com.clinic.entity.gui.GuiUserContact;
import com.clinic.entity.param.Index;
import com.clinic.util.CommonUtil;
import com.clinic.util.ConvertUtil;

@Component
public class DoctorLogic {
	
	@Autowired
	private DoctorAccessor doctorAccessor;
	
	@Autowired
	private UserContactAccessor userContactAccessor;
	
	
	public GuiDoctor insertDoctor(GuiDoctor guiDoctor) {
		
		Doctor doctor = ConvertUtil.getDoctorByGuiDoctor(guiDoctor, new Doctor());
		Doctor iDoctor = doctorAccessor.insertOrUpdate(doctor);
		
		GuiUserContact guiContact = guiDoctor.getContact();
		UserContact contact = ConvertUtil.getUserContactByGuiUserContact(guiContact, new UserContact());
		contact.setUser(iDoctor);
		UserContact iContact = userContactAccessor.insertOrUpdate(contact);
		
		GuiDoctor uDoctor = ConvertUtil.getGuiDoctorByDoctor(iDoctor);
		GuiUserContact uContact = ConvertUtil.getGuiUserContactByUserContact(iContact);
		uContact.setUser(uDoctor);
		
		uDoctor.setContact(uContact);
		
		return uDoctor;
	}
	
	public GuiDoctor updateDoctor(GuiDoctor guiDoctor) {
		
		Doctor doctor = doctorAccessor.getDoctorByUserId(guiDoctor.getUserId());
		Doctor oDoctor = ConvertUtil.getDoctorByGuiDoctor(guiDoctor, doctor);
		UserContact contact = doctor.getContact();
		if(contact == null) {
			contact = new UserContact();
		}
		UserContact oContact = ConvertUtil.getUserContactByGuiUserContact(guiDoctor.getContact(), contact);
		oContact.setUser(oDoctor);
		oDoctor.setContact(oContact);
		Doctor uDoctor = doctorAccessor.insertOrUpdate(oDoctor);
		return ConvertUtil.getGuiDoctorByDoctor(uDoctor);
	}
	
	@Transactional
	public GuiDoctor getDoctorDetailsById(long id) {
		
		Doctor doctor = doctorAccessor.getDoctorByUserId(id);
		GuiDoctor guiDoctor = ConvertUtil.getGuiDoctorByDoctor(doctor);
		guiDoctor.setContact(ConvertUtil.getGuiUserContactByUserContact(doctor.getContact()));
		return guiDoctor;
	}
	
	public boolean isNotAvailableDoctor(GuiDoctor guiDoctor) {
		
		return !isAvailableDoctor(guiDoctor);
	}
	
	public boolean isAvailableDoctor(GuiDoctor guiDoctor) {
		
		String regNo = guiDoctor.getRegNo();
		Doctor result = doctorAccessor.getDoctorByRegNo(regNo);
		return (result != null);
	}
	
	public boolean isValidDoctorUpdate(GuiDoctor guiDoctor) {
		
		String regNo = guiDoctor.getRegNo();
		Doctor result = doctorAccessor.getDoctorByRegNo(regNo);
		return (result.getUserId() == guiDoctor.getUserId());
	}
	
	public List<GuiDoctor> getDoctorListByTerm(String term, String column, Index index) {
		List<Doctor> doctorList = doctorAccessor.getOrderedDoctorsByTerm(term, column, index);		
		return getGuiDoctorsByDoctors(doctorList);
	}
	
	@Transactional
	public List<GuiDoctor> getDoctorList(Index index) {
		List<Doctor> doctorList = doctorAccessor.getAllDoctors(index);
		return getGuiDoctorsByDoctors(doctorList);
	}
	
	public void deleteDoctorDetailsById(long id) {
		Doctor doctor = doctorAccessor.getDoctorByUserId(id);
		if (doctor != null) {
			// TODO delete other related data before ... appointments, contacts... etc
			doctorAccessor.delete(doctor);
		}
	}
	
	private List<GuiDoctor> getGuiDoctorsByDoctors(List<Doctor> doctorList) {
		List<GuiDoctor> result = new ArrayList<>();
		for (Doctor doctor : doctorList) {
			result.add(ConvertUtil.getGuiDoctorByDoctor(doctor));
		}
		return result;
	}
	
	@Transactional
	public boolean isValidRegNo(GuiDoctor guiDoctor) {
		Doctor doctor = doctorAccessor.getDoctorByRegNo(guiDoctor.getRegNo());
		return (doctor == null);
	}
	
	public GuiPagination getPaginationOfDoctors(int page) {		
		int total = doctorAccessor.countDoctors();
		return CommonUtil.getPaginationInfo(page, total);
	}
	
	public GuiPagination getPaginationOfDoctorsByTerm(String term, String column, int page) {
		int total = doctorAccessor.countOrderedDoctorsByTerm(term, column);
		return CommonUtil.getPaginationInfo(page, total);
	}
	
}
